package com.ssy.lingxi.marketing.serviceimpl;

import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.constant.marketing.MerchantCouponTypeEnum;
import com.ssy.lingxi.common.constant.marketing.PlatformCouponTypeEnum;
import com.ssy.lingxi.common.model.bo.MemberAndRoleIdBO;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.marketing.entity.activity.ActivityGoodsCouponDO;
import com.ssy.lingxi.marketing.entity.coupon.*;
import com.ssy.lingxi.marketing.model.bo.CanReceiveCouponBO;
import com.ssy.lingxi.marketing.model.bo.MobileMerchantActivityGoodsCouponBO;
import com.ssy.lingxi.marketing.model.bo.ReceiveCouponBelongTypeBO;
import com.ssy.lingxi.marketing.model.constant.CanReceiveEnum;
import com.ssy.lingxi.marketing.model.constant.MerchantCouponEffectiveTypeEnum;
import com.ssy.lingxi.marketing.model.constant.PlatformCouponEffectiveTypeEnum;
import com.ssy.lingxi.marketing.model.vo.coupon.request.BelongTypeCouponRequest;
import com.ssy.lingxi.marketing.model.vo.coupon.response.MobileCouponResponse;
import com.ssy.lingxi.marketing.repository.*;
import com.ssy.lingxi.marketing.service.ICouponReceiveService;
import com.ssy.lingxi.marketing.serviceimpl.component.SuitableMemberInfoComponent;
import com.ssy.lingxi.marketing.serviceimpl.component.coupon.CouponQueryComponent;
import com.ssy.lingxi.marketing.serviceimpl.component.coupon.CouponReceiveCheckRuleComponent;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.AtSubMemberSuitableMemberVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.PfSubMemberSuitableMemberVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 优惠券领取服务实现类
 *
 * @author yzc
 * @version 2.0.0
 * @date 2021/9/6
 */
@Slf4j
@Service
public class CouponReceiveServiceImpl implements ICouponReceiveService {

    @Resource
    private MerchantCouponRepository merchantCouponRepository;
    @Resource
    private PlatformCouponRepository platformCouponRepository;
    @Resource
    private CouponReceiveCheckRuleComponent couponReceiveCheckRuleComponent;
    @Resource
    private CouponCategoryRepository couponCategoryRepository;
    @Resource
    private CouponBrandRepository couponBrandRepository;
    @Resource
    private CouponGoodsRepository couponGoodsRepository;
    @Resource
    private ActivityGoodsCouponRepository activityGoodsCouponRepository;
    @Resource
    private SuitableMemberInfoComponent suitableMemberInfoComponent;
    @Resource
    private CouponQueryComponent couponQueryComponent;

    @Override
    public Wrapper<List<CanReceiveCouponBO>> checkReceiveCoupon(UserLoginCacheDTO loginUser, ReceiveCouponBelongTypeBO couponBelongTypeBO) {
        Long shopId = couponBelongTypeBO.getShopId();
        if (Objects.isNull(shopId)) {
            log.error("校验平台优惠券、商家优惠券是否可领取, shopId为空");
            return Wrapper.success(Collections.emptyList());
        }

        List<BelongTypeCouponRequest> receiveCouponRequestList = couponBelongTypeBO.getCouponList();
        for (BelongTypeCouponRequest belongTypeCouponRequest : receiveCouponRequestList) {
            if (Objects.isNull(belongTypeCouponRequest.getBelongType())
                    || Objects.isNull(belongTypeCouponRequest.getCouponId())) {
                log.error("校验平台优惠券、商家优惠券是否可领取, belongType或couponId为空");
                return Wrapper.success(Collections.emptyList());
            }
        }

        // 根据所属类型分组
        Map<Integer, List<BelongTypeCouponRequest>> receiveCouponMap = receiveCouponRequestList.stream().collect(Collectors.groupingBy(BelongTypeCouponRequest::getBelongType));

        // 返回结果集
        List<CanReceiveCouponBO> resultList = new ArrayList<>();

        // 平台优惠券
        List<BelongTypeCouponRequest> platformReceiveCouponList = receiveCouponMap.get(BelongTypeEnum.PLATFORM.getCode());
        if (!CollectionUtils.isEmpty(platformReceiveCouponList)) {
            List<Long> couponIds = platformReceiveCouponList.stream().map(BelongTypeCouponRequest::getCouponId).collect(Collectors.toList());
            Wrapper<List<CanReceiveCouponBO>> platformCouponWrapper = checkPlatformCouponDetailReceive(loginUser, shopId, couponIds);
            if (ResponseCode.SUCCESS.getCode() != platformCouponWrapper.getCode()) {
                log.error("领取平台优惠券, errCode: {}, errMsg: {}", platformCouponWrapper.getCode(), platformCouponWrapper.getMessage());
            }
            if (!CollectionUtils.isEmpty(platformCouponWrapper.getData())) {
                resultList.addAll(platformCouponWrapper.getData());
            }

        }

        // 商家优惠券
        List<BelongTypeCouponRequest> merchantReceiveCouponList = receiveCouponMap.get(BelongTypeEnum.MERCHANT.getCode());
        if (!CollectionUtils.isEmpty(merchantReceiveCouponList)) {
            List<Long> couponIds = merchantReceiveCouponList.stream().map(BelongTypeCouponRequest::getCouponId).collect(Collectors.toList());
            Wrapper<List<CanReceiveCouponBO>> merchantCouponWrapper = checkMerchantCouponDetailReceive(loginUser, shopId, couponIds);
            if (ResponseCode.SUCCESS.getCode() != merchantCouponWrapper.getCode()) {
                log.error("领取商家优惠券, errCode: {}, errMsg: {}", merchantCouponWrapper.getCode(), merchantCouponWrapper.getMessage());
            }
            if (!CollectionUtils.isEmpty(merchantCouponWrapper.getData())) {
                resultList.addAll(merchantCouponWrapper.getData());
            }
        }

        return Wrapper.success(resultList);
    }

    @Override
    public Wrapper<List<CanReceiveCouponBO>> checkPlatformCouponDetailReceive(UserLoginCacheDTO loginUser, Long shopId, List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询平台优惠券
        List<PlatformCouponDO> platformCouponDOList = couponQueryComponent.selectPlatformCouponExecutingById(ids);
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询会员关系(需会员登录)
        PfSubMemberSuitableMemberVO subMemberSuitableMemberVO = null;
        if (Objects.nonNull(loginUser)) {
            subMemberSuitableMemberVO = suitableMemberInfoComponent.getPlatformSubMemberSuitableMember(loginUser.getMemberId(), loginUser.getMemberRoleId());
            if (Objects.isNull(subMemberSuitableMemberVO)) {
                return Wrapper.success();
            }
        }

        List<CanReceiveCouponBO> canReceiveCouponBOList = new ArrayList<>();
        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            CanReceiveCouponBO canReceiveCouponBO = new CanReceiveCouponBO();

            CanReceiveEnum canReceiveEnum = couponReceiveCheckRuleComponent.checkPlatformCanReceiveComplete(loginUser, platformCouponDO, shopId, subMemberSuitableMemberVO);
            canReceiveCouponBO.setCanReceive(canReceiveEnum);

            canReceiveCouponBO.setCouponId(platformCouponDO.getId());
            canReceiveCouponBO.setBelongType(BelongTypeEnum.PLATFORM.getCode());
            canReceiveCouponBO.setName(platformCouponDO.getName());
            canReceiveCouponBO.setType(platformCouponDO.getType());
            canReceiveCouponBO.setTypeName(PlatformCouponTypeEnum.getCodeMessage(platformCouponDO.getType()));
            canReceiveCouponBO.setReleaseTimeStart(platformCouponDO.getReleaseTimeStart());
            canReceiveCouponBO.setReleaseTimeEnd(platformCouponDO.getEffectiveTimeEnd());
            canReceiveCouponBO.setDenomination(platformCouponDO.getDenomination());
            canReceiveCouponBO.setGetWay(platformCouponDO.getGetWay());
            canReceiveCouponBO.setUseConditionMoney(platformCouponDO.getUseConditionMoney());
            canReceiveCouponBO.setEffectiveType(platformCouponDO.getEffectiveType());
            canReceiveCouponBO.setEffectiveTimeStart(platformCouponDO.getEffectiveTimeStart());
            canReceiveCouponBO.setEffectiveTimeEnd(platformCouponDO.getEffectiveTimeEnd());
            canReceiveCouponBO.setInvalidDay(platformCouponDO.getInvalidDay());
            canReceiveCouponBO.setCreateTime(platformCouponDO.getCreateTime());

            canReceiveCouponBOList.add(canReceiveCouponBO);
        }

        return Wrapper.success(canReceiveCouponBOList);
    }

    @Override
    public Wrapper<List<CanReceiveCouponBO>> checkMerchantCouponDetailReceive(UserLoginCacheDTO loginUser, Long shopId, List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询商家优惠券
        List<MerchantCouponDO> merchantCouponDOList = couponQueryComponent.selectMerchantCouponExecutingById(ids);
        if (CollectionUtils.isEmpty(merchantCouponDOList)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询会员关系
        List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList = null;
        if (Objects.nonNull(loginUser)) {
            subMemberSuitableMemberVOList = suitableMemberInfoComponent.listAbilitySubMemberSuitableMember(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    merchantCouponDOList.stream().map(e -> new MemberAndRoleIdBO(e.getMemberId(), e.getRoleId())).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(subMemberSuitableMemberVOList)) {
                return Wrapper.success(Collections.emptyList());
            }
        }

        List<CanReceiveCouponBO> canReceiveCouponBOList = new ArrayList<>();
        for (MerchantCouponDO merchantCouponDO : merchantCouponDOList) {
            CanReceiveCouponBO canReceiveCouponBO = new CanReceiveCouponBO();
            canReceiveCouponBO.setCouponId(merchantCouponDO.getId());
            canReceiveCouponBO.setBelongType(BelongTypeEnum.MERCHANT.getCode());
            canReceiveCouponBO.setName(merchantCouponDO.getName());
            canReceiveCouponBO.setType(merchantCouponDO.getType());
            canReceiveCouponBO.setTypeName(MerchantCouponTypeEnum.getCodeMessage(merchantCouponDO.getType()));
            canReceiveCouponBO.setReleaseTimeStart(merchantCouponDO.getReleaseTimeStart());
            canReceiveCouponBO.setReleaseTimeEnd(merchantCouponDO.getEffectiveTimeEnd());
            canReceiveCouponBO.setDenomination(merchantCouponDO.getDenomination());
            canReceiveCouponBO.setGetWay(merchantCouponDO.getGetWay());
            canReceiveCouponBO.setUseConditionMoney(merchantCouponDO.getUseConditionMoney());
            canReceiveCouponBO.setEffectiveType(merchantCouponDO.getEffectiveType());
            canReceiveCouponBO.setEffectiveTimeStart(merchantCouponDO.getEffectiveTimeStart());
            canReceiveCouponBO.setEffectiveTimeEnd(merchantCouponDO.getEffectiveTimeEnd());
            canReceiveCouponBO.setInvalidDay(merchantCouponDO.getInvalidDay());
            canReceiveCouponBO.setCreateTime(merchantCouponDO.getCreateTime());

            CanReceiveEnum canReceiveEnum = couponReceiveCheckRuleComponent.checkMerchantCanReceiveComplete(loginUser, merchantCouponDO, shopId, subMemberSuitableMemberVOList);
            canReceiveCouponBO.setCanReceive(canReceiveEnum);

            canReceiveCouponBOList.add(canReceiveCouponBO);
        }

        return Wrapper.success(canReceiveCouponBOList);
    }

    @Override
    public List<MobileMerchantActivityGoodsCouponBO> listMerchantActivityGoodsCoupon(UserLoginCacheDTO loginUser, Long shopId, List<Long> ids) {
        if (Objects.isNull(shopId) || CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }

        // 活动赠品优惠券
        List<ActivityGoodsCouponDO> activityGoodsCouponDOList = activityGoodsCouponRepository.findByCouponIdIn(ids);
        // couponId - List<ActivityGoodsCouponDO>
        Map<Long, List<ActivityGoodsCouponDO>> goodsCouponDOMap = activityGoodsCouponDOList.stream().collect(Collectors.groupingBy(ActivityGoodsCouponDO::getCouponId));

        // 赠品优惠券为非0元抵扣券
        List<Integer> typeList = Arrays.asList(
                MerchantCouponTypeEnum.COMMON.getCode(),
                MerchantCouponTypeEnum.CATEGORY.getCode(),
                MerchantCouponTypeEnum.BRAND.getCode(),
                MerchantCouponTypeEnum.COMMODITY.getCode());
        List<Long> couponIds = activityGoodsCouponDOList.stream().map(ActivityGoodsCouponDO::getCouponId).collect(Collectors.toList());
        List<MerchantCouponDO> merchantCouponDOList = merchantCouponRepository.findAll((Specification<MerchantCouponDO>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.and(root.get("id").in(couponIds)));
            predicateList.add(cb.in(root.get("type")).value(typeList));
            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        });

        // 查询会员关系
        List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList = null;
        if (Objects.nonNull(loginUser)) {
            subMemberSuitableMemberVOList = suitableMemberInfoComponent.listAbilitySubMemberSuitableMember(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    merchantCouponDOList.stream().map(e -> new MemberAndRoleIdBO(e.getMemberId(), e.getRoleId())).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(subMemberSuitableMemberVOList)) {
                return Collections.emptyList();
            }
        }

        // 匹配规则
        List<MerchantCouponDO> filterMerchantCouponList = new ArrayList<>();
        for (MerchantCouponDO merchantCouponDO : merchantCouponDOList) {
            if (!couponReceiveCheckRuleComponent.checkMerchantCanReceive(loginUser, merchantCouponDO, shopId, subMemberSuitableMemberVOList)) {
                continue;
            }

            filterMerchantCouponList.add(merchantCouponDO);
        }

        List<MobileMerchantActivityGoodsCouponBO> resultList = filterMerchantCouponList.stream().map(merchantCouponDO -> {
            MobileMerchantActivityGoodsCouponBO mobileMerchantActivityGoodsCouponBO = new MobileMerchantActivityGoodsCouponBO();
            mobileMerchantActivityGoodsCouponBO.setCouponId(merchantCouponDO.getId());
            mobileMerchantActivityGoodsCouponBO.setName(merchantCouponDO.getName());
            mobileMerchantActivityGoodsCouponBO.setTypeName(MerchantCouponTypeEnum.getCodeMessage(merchantCouponDO.getType()));
            mobileMerchantActivityGoodsCouponBO.setDenomination(merchantCouponDO.getDenomination());
            mobileMerchantActivityGoodsCouponBO.setUseConditionMoney(merchantCouponDO.getUseConditionMoney());
            mobileMerchantActivityGoodsCouponBO.setEffectiveType(merchantCouponDO.getEffectiveType());
            mobileMerchantActivityGoodsCouponBO.setEffectiveTypeName(MerchantCouponEffectiveTypeEnum.getCodeMessage(merchantCouponDO.getEffectiveType()));
            mobileMerchantActivityGoodsCouponBO.setEffectiveTimeStart(merchantCouponDO.getEffectiveTimeStart());
            mobileMerchantActivityGoodsCouponBO.setEffectiveTimeEnd(merchantCouponDO.getEffectiveTimeEnd());
            mobileMerchantActivityGoodsCouponBO.setInvalidDay(merchantCouponDO.getInvalidDay());
            // productId
            List<ActivityGoodsCouponDO> mapList = goodsCouponDOMap.get(merchantCouponDO.getId());
            List<Long> productIds = Collections.emptyList();
            if (Objects.nonNull(mapList)) {
                productIds = mapList.stream().map(e -> e.getActivityGoods().getProductId()).distinct().collect(Collectors.toList());
            }
            mobileMerchantActivityGoodsCouponBO.setProductIds(productIds);
            return mobileMerchantActivityGoodsCouponBO;
        }).collect(Collectors.toList());

        return resultList;
    }

    @Override
    public List<MobileMerchantActivityGoodsCouponBO> listMerchantActivityGoodsCoupon(List<Long> ids) {
        // 活动赠品优惠券
        List<ActivityGoodsCouponDO> activityGoodsCouponDOList = activityGoodsCouponRepository.findByCouponIdIn(ids);
        // couponId - List<ActivityGoodsCouponDO>
        Map<Long, List<ActivityGoodsCouponDO>> goodsCouponDOMap = activityGoodsCouponDOList.stream().collect(Collectors.groupingBy(ActivityGoodsCouponDO::getCouponId));

        // 赠品优惠券为非0元抵扣券
        List<Integer> typeList = Arrays.asList(
                MerchantCouponTypeEnum.COMMON.getCode(),
                MerchantCouponTypeEnum.CATEGORY.getCode(),
                MerchantCouponTypeEnum.BRAND.getCode(),
                MerchantCouponTypeEnum.COMMODITY.getCode());
        List<Long> couponIds = activityGoodsCouponDOList.stream().map(ActivityGoodsCouponDO::getCouponId).collect(Collectors.toList());
        List<MerchantCouponDO> merchantCouponDOList = merchantCouponRepository.findAll((Specification<MerchantCouponDO>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.and(root.get("id").in(couponIds)));
            predicateList.add(cb.in(root.get("type")).value(typeList));
            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        });

        List<MobileMerchantActivityGoodsCouponBO> resultList = merchantCouponDOList.stream().map(merchantCouponDO -> {
            MobileMerchantActivityGoodsCouponBO mobileMerchantActivityGoodsCouponBO = new MobileMerchantActivityGoodsCouponBO();
            mobileMerchantActivityGoodsCouponBO.setCouponId(merchantCouponDO.getId());
            mobileMerchantActivityGoodsCouponBO.setName(merchantCouponDO.getName());
            mobileMerchantActivityGoodsCouponBO.setTypeName(MerchantCouponTypeEnum.getCodeMessage(merchantCouponDO.getType()));
            mobileMerchantActivityGoodsCouponBO.setDenomination(merchantCouponDO.getDenomination());
            mobileMerchantActivityGoodsCouponBO.setUseConditionMoney(merchantCouponDO.getUseConditionMoney());
            mobileMerchantActivityGoodsCouponBO.setEffectiveType(merchantCouponDO.getEffectiveType());
            mobileMerchantActivityGoodsCouponBO.setEffectiveTypeName(MerchantCouponEffectiveTypeEnum.getCodeMessage(merchantCouponDO.getEffectiveType()));
            mobileMerchantActivityGoodsCouponBO.setEffectiveTimeStart(merchantCouponDO.getEffectiveTimeStart());
            mobileMerchantActivityGoodsCouponBO.setEffectiveTimeEnd(merchantCouponDO.getEffectiveTimeEnd());
            mobileMerchantActivityGoodsCouponBO.setInvalidDay(merchantCouponDO.getInvalidDay());
            // productId
            List<ActivityGoodsCouponDO> mapList = goodsCouponDOMap.get(merchantCouponDO.getId());
            List<Long> productIds = Collections.emptyList();
            if (Objects.nonNull(mapList)) {
                productIds = mapList.stream().map(e -> e.getActivityGoods().getProductId()).distinct().collect(Collectors.toList());
            }
            mobileMerchantActivityGoodsCouponBO.setProductIds(productIds);
            return mobileMerchantActivityGoodsCouponBO;
        }).collect(Collectors.toList());

        return resultList;
    }

    @Override
    public Wrapper<List<MobileCouponResponse>> listPlatformCouponCanReceiveComplete(UserLoginCacheDTO loginUser, Long shopId) {
        List<PlatformCouponDO> platformCouponDOList = couponQueryComponent.selectPlatformCouponExecuting();
        if (CollectionUtils.isEmpty(platformCouponDOList)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询会员关系(需会员登录)
        PfSubMemberSuitableMemberVO subMemberSuitableMemberVO = null;
        if (Objects.nonNull(loginUser)) {
            subMemberSuitableMemberVO = suitableMemberInfoComponent.getPlatformSubMemberSuitableMember(loginUser.getMemberId(), loginUser.getMemberRoleId());
            if (Objects.isNull(subMemberSuitableMemberVO)) {
                return Wrapper.success(Collections.emptyList());
            }
        }

        List<MobileCouponResponse> resultList = new ArrayList<>();
        for (PlatformCouponDO platformCouponDO : platformCouponDOList) {
            MobileCouponResponse mobileCouponResponse = new MobileCouponResponse();
            CanReceiveEnum canReceiveEnum = couponReceiveCheckRuleComponent.checkPlatformCanReceiveComplete(loginUser, platformCouponDO, shopId, subMemberSuitableMemberVO);
            if (CanReceiveEnum.NO_MATCH.equals(canReceiveEnum)) {
                continue;
            }

            mobileCouponResponse.setCouponId(platformCouponDO.getId());
            mobileCouponResponse.setBelongType(BelongTypeEnum.PLATFORM.getCode());
            mobileCouponResponse.setName(platformCouponDO.getName());
            mobileCouponResponse.setType(platformCouponDO.getType());
            mobileCouponResponse.setTypeName(PlatformCouponTypeEnum.getCodeMessage(platformCouponDO.getType()));
            mobileCouponResponse.setDenomination(platformCouponDO.getDenomination());
            mobileCouponResponse.setUseConditionMoney(platformCouponDO.getUseConditionMoney());
            mobileCouponResponse.setEffectiveType(platformCouponDO.getEffectiveType());
            mobileCouponResponse.setEffectiveTypeName(PlatformCouponEffectiveTypeEnum.getCodeMessage(platformCouponDO.getEffectiveType()));
            mobileCouponResponse.setEffectiveTimeStart(platformCouponDO.getEffectiveTimeStart());
            mobileCouponResponse.setEffectiveTimeEnd(platformCouponDO.getEffectiveTimeEnd());
            mobileCouponResponse.setInvalidDay(platformCouponDO.getInvalidDay());
            mobileCouponResponse.setCompleteReceive(canReceiveEnum.getCode());

            resultList.add(mobileCouponResponse);
        }

        return Wrapper.success(resultList);
    }

    @Override
    public Wrapper<List<MobileCouponResponse>> listMerchantCouponCanReceiveComplete(UserLoginCacheDTO loginUser, Long shopId, Long memberId, Long roleId) {
        // 查询优惠券
        List<MerchantCouponDO> merchantCouponDOList = couponQueryComponent.selectMerchantCouponExecutingByMember(memberId, roleId);
        if (CollectionUtils.isEmpty(merchantCouponDOList)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询会员关系
        List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList = null;
        if (Objects.nonNull(loginUser)) {
            subMemberSuitableMemberVOList = suitableMemberInfoComponent.listAbilitySubMemberSuitableMember(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    merchantCouponDOList.stream().map(e -> new MemberAndRoleIdBO(e.getMemberId(), e.getRoleId())).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(subMemberSuitableMemberVOList)) {
                return Wrapper.success(Collections.emptyList());
            }
        }

        List<MobileCouponResponse> resultList = new ArrayList<>();
        for (MerchantCouponDO merchantCouponDO : merchantCouponDOList) {
            MobileCouponResponse mobileCouponResponse = new MobileCouponResponse();

            CanReceiveEnum canReceiveEnum = couponReceiveCheckRuleComponent.checkMerchantCanReceiveComplete(loginUser, merchantCouponDO, shopId, subMemberSuitableMemberVOList);
            if (CanReceiveEnum.NO_MATCH.equals(canReceiveEnum)) {
                continue;
            }

            if (MerchantCouponTypeEnum.COMMON.getCode().equals(merchantCouponDO.getType())) {
                // 通用 ignore
            } else if (MerchantCouponTypeEnum.CATEGORY.getCode().equals(merchantCouponDO.getType())) {
                // 品类
                List<CouponCategoryDO> couponCategoryDOList = couponCategoryRepository.findAllByCouponId(merchantCouponDO.getId());
                mobileCouponResponse.setCategoryIds(couponCategoryDOList.stream().map(CouponCategoryDO::getCategoryId).collect(Collectors.toList()));
            } else if (MerchantCouponTypeEnum.BRAND.getCode().equals(merchantCouponDO.getType())) {
                // 品牌
                List<CouponBrandDO> couponBrandDOList = couponBrandRepository.findAllByCouponId(merchantCouponDO.getId());
                mobileCouponResponse.setBrandIds(couponBrandDOList.stream().map(CouponBrandDO::getBrandId).collect(Collectors.toList()));
            } else if (MerchantCouponTypeEnum.COMMODITY.getCode().equals(merchantCouponDO.getType())) {
                // 商品
                List<CouponGoodsDO> couponGoodsDOList = couponGoodsRepository.findAllByBelongTypeAndCouponId(BelongTypeEnum.MERCHANT.getCode(), merchantCouponDO.getId());
                mobileCouponResponse.setProductIds(couponGoodsDOList.stream().map(CouponGoodsDO::getProductId).distinct().collect(Collectors.toList()));
            }

            mobileCouponResponse.setCouponId(merchantCouponDO.getId());
            mobileCouponResponse.setBelongType(BelongTypeEnum.MERCHANT.getCode());
            mobileCouponResponse.setName(merchantCouponDO.getName());
            mobileCouponResponse.setType(merchantCouponDO.getType());
            mobileCouponResponse.setTypeName(MerchantCouponTypeEnum.getCodeMessage(merchantCouponDO.getType()));
            mobileCouponResponse.setDenomination(merchantCouponDO.getDenomination());
            mobileCouponResponse.setUseConditionMoney(merchantCouponDO.getUseConditionMoney());
            mobileCouponResponse.setEffectiveType(merchantCouponDO.getEffectiveType());
            mobileCouponResponse.setEffectiveTypeName(MerchantCouponEffectiveTypeEnum.getCodeMessage(merchantCouponDO.getEffectiveType()));
            mobileCouponResponse.setEffectiveTimeStart(merchantCouponDO.getEffectiveTimeStart());
            mobileCouponResponse.setEffectiveTimeEnd(merchantCouponDO.getEffectiveTimeEnd());
            mobileCouponResponse.setInvalidDay(merchantCouponDO.getInvalidDay());
            mobileCouponResponse.setCompleteReceive(canReceiveEnum.getCode());

            resultList.add(mobileCouponResponse);
        }

        return Wrapper.success(resultList);
    }

    @Override
    public Wrapper<List<MobileCouponResponse>> listGoodsMerchantCoupon(UserLoginCacheDTO loginUser, Long shopId, Long memberId, Long roleId, Long skuId, Long categoryId, Long brandId) {
        // 查询优惠券
        List<MerchantCouponDO> merchantCouponDOList = couponQueryComponent.selectMerchantCouponExecutingByMember(memberId, roleId);
        if (CollectionUtils.isEmpty(merchantCouponDOList)) {
            return Wrapper.success(Collections.emptyList());
        }

        // 查询会员关系
        List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList = null;
        if (Objects.nonNull(loginUser)) {
            subMemberSuitableMemberVOList = suitableMemberInfoComponent.listAbilitySubMemberSuitableMember(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    merchantCouponDOList.stream().map(e -> new MemberAndRoleIdBO(e.getMemberId(), e.getRoleId())).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(subMemberSuitableMemberVOList)) {
                return Wrapper.success(Collections.emptyList());
            }
        }

        List<MobileCouponResponse> resultList = new ArrayList<>();
        for (MerchantCouponDO merchantCouponDO : merchantCouponDOList) {
            MobileCouponResponse mobileCouponResponse = new MobileCouponResponse();

            CanReceiveEnum canReceiveEnum = couponReceiveCheckRuleComponent.checkMerchantCanReceiveComplete(loginUser, merchantCouponDO, shopId, subMemberSuitableMemberVOList);
            if (CanReceiveEnum.NO_MATCH.equals(canReceiveEnum)) {
                continue;
            }

            if (MerchantCouponTypeEnum.COMMON.getCode().equals(merchantCouponDO.getType())) {
                // 通用 ignore
            } else if (MerchantCouponTypeEnum.CATEGORY.getCode().equals(merchantCouponDO.getType())) {
                if (Objects.isNull(categoryId)) {
                    continue;
                }
                // 品类
                List<CouponCategoryDO> couponCategoryDOList = couponCategoryRepository.findAllByCouponId(merchantCouponDO.getId());
                if (couponCategoryDOList.stream().noneMatch(e -> categoryId.equals(e.getCategoryId()))) {
                    continue;
                }
                mobileCouponResponse.setCategoryIds(couponCategoryDOList.stream().map(CouponCategoryDO::getCategoryId).collect(Collectors.toList()));
            } else if (MerchantCouponTypeEnum.BRAND.getCode().equals(merchantCouponDO.getType())) {
                if (Objects.isNull(brandId)) {
                    continue;
                }
                // 品牌
                List<CouponBrandDO> couponBrandDOList = couponBrandRepository.findAllByCouponId(merchantCouponDO.getId());
                if (couponBrandDOList.stream().noneMatch(e -> brandId.equals(e.getBrandId()))) {
                    continue;
                }
                mobileCouponResponse.setBrandIds(couponBrandDOList.stream().map(CouponBrandDO::getBrandId).collect(Collectors.toList()));
            } else if (MerchantCouponTypeEnum.COMMODITY.getCode().equals(merchantCouponDO.getType())) {
                if (Objects.isNull(skuId)) {
                    continue;
                }
                // 商品
                List<CouponGoodsDO> couponGoodsDOList = couponGoodsRepository.findAllByBelongTypeAndCouponId(BelongTypeEnum.MERCHANT.getCode(), merchantCouponDO.getId());
                if (couponGoodsDOList.stream().noneMatch(e -> skuId.equals(e.getSkuId()))) {
                    continue;
                }
                mobileCouponResponse.setProductIds(couponGoodsDOList.stream().map(CouponGoodsDO::getProductId).distinct().collect(Collectors.toList()));
            }

            mobileCouponResponse.setCouponId(merchantCouponDO.getId());
            mobileCouponResponse.setBelongType(BelongTypeEnum.MERCHANT.getCode());
            mobileCouponResponse.setName(merchantCouponDO.getName());
            mobileCouponResponse.setType(merchantCouponDO.getType());
            mobileCouponResponse.setTypeName(MerchantCouponTypeEnum.getCodeMessage(merchantCouponDO.getType()));
            mobileCouponResponse.setDenomination(merchantCouponDO.getDenomination());
            mobileCouponResponse.setUseConditionMoney(merchantCouponDO.getUseConditionMoney());
            mobileCouponResponse.setEffectiveType(merchantCouponDO.getEffectiveType());
            mobileCouponResponse.setEffectiveTypeName(MerchantCouponEffectiveTypeEnum.getCodeMessage(merchantCouponDO.getEffectiveType()));
            mobileCouponResponse.setEffectiveTimeStart(merchantCouponDO.getEffectiveTimeStart());
            mobileCouponResponse.setEffectiveTimeEnd(merchantCouponDO.getEffectiveTimeEnd());
            mobileCouponResponse.setInvalidDay(merchantCouponDO.getInvalidDay());
            mobileCouponResponse.setCompleteReceive(canReceiveEnum.getCode());

            resultList.add(mobileCouponResponse);
        }

        return Wrapper.success(resultList);
    }
}
